package cn.edu.pzhu.javaweb.util;

import javax.sql.DataSource;

import org.junit.jupiter.api.Test;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import com.mchange.v2.c3p0.DataSources;

/**
 * C3P0数据库连接池工具类
 */
public class C3P0Util {
    
    private static DataSource dataSource;
    
    static {
        initDataSource();
    }
    
    /**
     * 初始化数据源
     */
    private static void initDataSource() {
        try {
            // 让C3P0自动加载类路径下的c3p0-config.xml
            dataSource = new com.mchange.v2.c3p0.ComboPooledDataSource();
            System.out.println("C3P0连接池初始化成功！");
            
        } catch (Exception e) {
            System.err.println("C3P0连接池初始化失败，使用备用配置！");
            e.printStackTrace();
            initDataSourceWithBackup();
        }
    }
    
    /**
     * 备用配置方案
     */
    private static void initDataSourceWithBackup() {
        try {
            // 手动创建数据源
            DataSource unpooledDataSource = DataSources.unpooledDataSource(
                "jdbc:mysql://127.0.0.1:3306/filesys?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
                "root",
                "123456"
            );
            
            Properties poolProps = new Properties();
            poolProps.setProperty("c3p0.driverClass", "com.mysql.cj.jdbc.Driver");
            poolProps.setProperty("c3p0.initialPoolSize", "5");
            poolProps.setProperty("c3p0.maxPoolSize", "10");
            poolProps.setProperty("c3p0.checkoutTimeout", "3000");
            poolProps.setProperty("c3p0.minPoolSize", "3");
            poolProps.setProperty("c3p0.acquireIncrement", "2");
            poolProps.setProperty("c3p0.maxIdleTime", "1800");
            
            dataSource = DataSources.pooledDataSource(unpooledDataSource, poolProps);
            System.out.println("备用配置连接池初始化成功！");
            
        } catch (SQLException e) {
            System.err.println("备用配置也失败了！");
            throw new RuntimeException("数据库连接池初始化完全失败", e);
        }
    }
    
    /**
     * 获取数据库连接 - 这是您测试代码中需要的方法
     * @return Connection 数据库连接
     * @throws SQLException 数据库异常
     */
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    
    /**
     * 获取数据源
     * @return DataSource 数据源对象
     */
    public static DataSource getDataSource() {
        return dataSource;
    }
    
    /**
     * 安全地关闭连接
     * @param conn 要关闭的连接
     */
    public static void closeConnection(Connection conn) {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                System.err.println("关闭数据库连接时发生错误！");
                e.printStackTrace();
            }
        }
    }
    
    /**
     * 关闭连接池
     */
    public static void closeDataSource() {
        if (dataSource != null) {
            try {
                if (dataSource instanceof com.mchange.v2.c3p0.ComboPooledDataSource) {
                    ((com.mchange.v2.c3p0.ComboPooledDataSource) dataSource).close();
                } else {
                    DataSources.destroy(dataSource);
                }
                System.out.println("C3P0连接池已关闭！");
            } catch (SQLException e) {
                System.err.println("关闭C3P0连接池时发生错误！");
                e.printStackTrace();
            }
        }
    }
    
    /**
     * 测试连接池功能 - 模拟您老师的测试代码
     */
    @Test
    public void testConnectionPool() {
        try {
            System.out.println("开始测试连接池...");
            for (int i = 1; i <= 11; i++) {
                Connection con = getConnection();
                System.out.println("第" + i + "次获取连接: " + con);
                if (i == 5) {
                    con.close();
                    System.out.println("第5次连接已关闭");
                }
                // 注意：其他连接没有关闭，测试连接池的最大连接数限制
            }
        } catch (SQLException e) {
            System.err.println("测试过程中出现异常: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
}